/*
 $Id$

 Copyright (C) 2006-2007 by David Cotton

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package fr.lna.chess.ui.action;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import fr.lna.chess.type.IMAGE;
import fr.lna.chess.type.ImageManager;
import fr.lna.chess.util.Message;
import static fr.lna.chess.type.MessageKey.*;

import fr.lna.util.EvenOddRowsRenderer;


/**
 * Boite de dialogue de l'option "A propos...".
 * 
 * @author bull
 */
@org.springframework.stereotype.Component("about.dialog")
public class AboutDialog
{




/** Panel principal de la boite de dialogue. */
  private static JOptionPane S_optionPane;

	@Autowired
	@Qualifier("image.source")
	private ImageManager imageSource;

	@Autowired
	@Qualifier("message.source")
	private Message messageSource;

/**
   * Renvoi, après l'avoir construit si nécessaire, le panel principal de la boite de dialogue.
   * 
   * @return Panel principal de la boite de dialogue.
   */
  private JOptionPane getOptionPane()
  {
    if (S_optionPane == null)
    {
      final JTabbedPane onglets =
          new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

      final JPanel auteur = new JPanel(new BorderLayout());
      final JLabel app =
          new JLabel(messageSource.getMessage(CHESS_APPLICATION_TITLE), imageSource.getImageIcon(IMAGE.ICON64), SwingConstants.CENTER);
      final Font ft = app.getFont();
      app.setFont(ft.deriveFont(Font.BOLD, ft.getSize() * 2.5F));
      auteur.add(app, BorderLayout.NORTH);
      final JPanel centre = new JPanel(new GridLayout(4, 1));
      final JLabel ver = new JLabel(messageSource.getMessage(APPLICATION_VERSION), SwingConstants.CENTER);
      ver.setFont(ft.deriveFont(Font.BOLD, ft.getSize() * 1.5F));
      centre.add(ver);
      centre.add(new JLabel(messageSource.getMessage(APPLICATION_AUTHOR), SwingConstants.CENTER));
      final JLabel traducteur =
          new JLabel(messageSource.getMessage("dialog.about.translater"), SwingConstants.CENTER);
      traducteur.setFont(ft.deriveFont(Font.ITALIC));
      centre.add(traducteur);
      if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE))
      {
        final JPanel panelWeb = new JPanel();
        final JButton boutonWeb = new JButton(APPLICATION_WEB);
        boutonWeb.setToolTipText(messageSource.getMessage("dialog.about.web.tooltip"));
        boutonWeb.addActionListener(new ActionListener()
        {
          /**
           * Lance le navigateur sur la page d'accueil du site de jChecs.
           * 
           * @param pEvt Evènement signalant le déclenchement du bouton.
           */
          public void actionPerformed(final ActionEvent pEvt)
          {
            assert pEvt != null;

            try
            {
              Desktop.getDesktop().browse(new URI(APPLICATION_WEB));
            }
            catch (final IOException e)
            {
              // Pas grave : on peut se passer de l'accès au site Web...
            }
            catch (final URISyntaxException e)
            {
              // Pas grave : on peut se passer de l'accès au site Web...
            }
          }
        });
        panelWeb.add(boutonWeb);
        centre.add(panelWeb);
      }
      else
      {
        centre.add(new JLabel(APPLICATION_WEB, SwingConstants.CENTER));
      }
      auteur.add(centre, BorderLayout.CENTER);
      final JTextArea remerciements = new JTextArea(messageSource.getMessage("dialog.about.thanks"));
      remerciements.setFont(ft.deriveFont(Font.ITALIC, ft.getSize() * 0.9F));
      remerciements.setLineWrap(true);
      remerciements.setWrapStyleWord(true);
      remerciements.setOpaque(false);
      remerciements.setForeground(Color.DARK_GRAY);
      remerciements.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.LIGHT_GRAY));
      auteur.add(remerciements, BorderLayout.SOUTH);
      onglets.add(messageSource.getMessage("dialog.about.author"), auteur);

      //onglets.add(messageSource.getMessage("dialog.about.license"), getLicensePanel());

      final TableModel modele = new AboutModel();
      final JTable proprietes = new JTable(modele);
      proprietes.getTableHeader().setReorderingAllowed(false);
      proprietes.setEnabled(false);
      proprietes.setRowSelectionAllowed(false);
      proprietes.setRowSorter(new TableRowSorter<TableModel>(modele));
      proprietes.setShowHorizontalLines(false);
      proprietes.setDefaultRenderer(Object.class, new EvenOddRowsRenderer());
      onglets.add(messageSource.getMessage("dialog.about.system"), new JScrollPane(proprietes));
      onglets.setPreferredSize(new Dimension(450, 300));

      S_optionPane = new JOptionPane(onglets, JOptionPane.PLAIN_MESSAGE);
    }

    assert S_optionPane != null;
    return S_optionPane;
  }

  /**
   * Affiche la boite de dialogue.
   * 
   * @param pParent Composant parent de la boite de dialogue (peut être à null).
   */
  public void showAboutDialog(final Component pParent)
  {
    final JDialog dlg = getOptionPane().createDialog(pParent, messageSource.getMessage("dialog.about.title"));
    dlg.pack();
    dlg.setResizable(false);
    dlg.setLocationRelativeTo(pParent);
    dlg.setVisible(true);
  }

  /**
   * Processus de chargement de la licence en tâche de fond.
   */
  private final class LicenseLoader extends Thread
  {
    /** Zone texte accueillant la licence. */
    private final JEditorPane _editorPane;

    /** URL de la licence. */
    private final URL _url;

    /**
     * Construit le processus.
     * 
     * @param pZoneTexte Zone texte accueillant la licence.
     * @param pURL URL de la licence.
     */
    LicenseLoader(final JEditorPane pZoneTexte, final URL pURL)
    {
      super("loadLicense");

      _editorPane = pZoneTexte;
      _url = pURL;

      setDaemon(true);
    }

    /**
     * Charge le texte de la licence en tâche de fond.
     */
    @Override
    public void run()
    {
      try
      {
        _editorPane.setPage(_url);
      }
      catch (final IOException e)
      {
        _editorPane.setText("<center><h3>This program is under GPL.</h3></center>");
      }
    }
  }

  /**
   * Modèle de données interne pour le tableau des propriétés.
   */
  private class AboutModel extends DefaultTableModel
  {
    /** Identifiant de la classe pour la sérialisation. */
    private static final long serialVersionUID = -5557358361119743070L;

    /** Liste des clés des propriétés système. */
    private final List<Object> _keys;

    /**
     * Constructeur par défaut.
     */
    public AboutModel()
    {
      _keys = new ArrayList<Object>(System.getProperties().keySet());

      setColumnCount(2);
      setRowCount(_keys.size());

      final String [] enTetes =
          { messageSource.getMessage("dialog.about.properties"), messageSource.getMessage("dialog.about.values"), };
      setColumnIdentifiers(enTetes);
    }

    /**
     * Renvoi le contenu d'une cellule.
     * 
     * @param pLigne Indice de la ligne.
     * @param pColonne Indice de la colonne.
     * @return Contenu de la cellule correspondante.
     */
    @Override
    public Object getValueAt(final int pLigne, final int pColonne)
    {
      assert (pLigne >= 0) && (pLigne < _keys.size());
      assert (pColonne == 0) || (pColonne == 1);

      String res = (String) _keys.get(pLigne);

      if (pColonne == 1)
      {
        res = System.getProperties().getProperty(res);
      }

      assert res != null;
      return res;
    }
  }
}
